package com.wys.utils.password;

import cn.hutool.crypto.digest.DigestUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DESUtil {

    private static final Logger logger = Logger.getLogger(DESUtil.class.getName());

    private static final String KEY_ALGORITHM_DESEDE = "DESede";//加密算法

    public static final String DEFAULT_KEY = "9058e4075fcbf0ec34382fb35baefe7fcccbd3f8a1154122525ca92ce56a2714";


    /**
     * 支持md5、sha256 、sha512
     *
     * @param text      密文
     * @param algorithm 加密方式
     * @return
     */
    public static String encryptMI(String text, String algorithm) {
        if (text == null || StringUtils.isEmpty(text.trim()))
            return "";
        try {
            StringBuilder sb = new StringBuilder();
            MessageDigest md = MessageDigest.getInstance(algorithm);
            md.update(text.getBytes(StandardCharsets.UTF_8));
            char[] chars = encode(md.digest(), true);
            for (int i = 0; i < chars.length; i++) {
                sb.append(i == 32 ? '#' : chars[i]);
            }
            return sb.toString();
        } catch (Exception e) {
            logger.log(Level.SEVERE, e.getMessage(), e.getCause());
        }
        return null;
    }

    public static String md5(String text) {
        return encryptMI(text, "MD5");
    }

    public static String SHA256(String text) {
        return encryptMI(text, "SHA-256");
    }

    public static char[] encode(byte[] data, boolean up) {
        char[] alphabets = (up ? "0123456789abcdef" : "0123456789ABCDEF").toCharArray();
        int len = data.length;
        char[] out = new char[len << 1];
        int i = 0;

        for (int var5 = 0; i < len; ++i) {
            out[var5++] = alphabets[(240 & data[i]) >>> 4];
            out[var5++] = alphabets[15 & data[i]];
        }

        return out;
    }

    /**
     * 得到3-DES的密钥匙
     * 根据接口规范，密钥匙为24个字节
     *
     * @param key
     * @return
     */
    public static byte[] hex(String key) {
        String f = md5(key);
        assert f != null;
        byte[] bkeys = f.getBytes();
        byte[] enk = new byte[24];
        for (int i = 0; i < 24; i++) {
            enk[i] = bkeys[i];
        }
        return enk;
    }

    /**
     * 3DES加密
     *
     * @param key    密钥，24位
     * @param srcStr 将加密的字符串
     * @return
     */
    public static String encrypt3Des(String key, String srcStr) {
        byte[] keybyte = hex(key);
        byte[] src = srcStr.getBytes();

        try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, KEY_ALGORITHM_DESEDE);
            //加密
            Cipher c1 = Cipher.getInstance(KEY_ALGORITHM_DESEDE);
            c1.init(Cipher.ENCRYPT_MODE, deskey);

            return Base64.encodeBase64String(c1.doFinal(src));
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
                 | IllegalBlockSizeException | BadPaddingException e) {
            logger.log(Level.SEVERE, "", e);
        }

        return null;
    }

    /**
     * 3DES解密
     *
     * @param key    加密密钥，长度为24字节
     * @param desStr 解密后的字符串
     * @return
     */
    public static String decrypt3Des(String key, String desStr) {
        Base64 base64 = new Base64();
        byte[] keybyte = hex(key);
        byte[] src = base64.decode(desStr);

        try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, KEY_ALGORITHM_DESEDE);
            //解密
            Cipher c1 = Cipher.getInstance(KEY_ALGORITHM_DESEDE);
            c1.init(Cipher.DECRYPT_MODE, deskey);

            return new String(c1.doFinal(src));
        } catch (Exception e) {
            logger.log(Level.SEVERE, "", e);
        }
        return null;
    }


    public static void main(String[] args) {
        String key = "430525fgh";
        String text = "430525fgh";
        System.out.println("-----------md5:" + DESUtil.SHA256("1"));
        System.out.println("-----------sha256:" + Arrays.toString(DESUtil.SHA256("1").split("#")));
        String s1 = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92";
        String s2 = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92";
        String s3 = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92";
        System.out.println("--------sha256Hex" + DigestUtil.sha256Hex("123456"));
        key = DESUtil.SHA256(key);
        System.out.println("=============key" + key);
        String pwd = DESUtil.encrypt3Des(key, text);

        String str = DESUtil.decrypt3Des("9058e4075fcbf0ec34382fb35baefe7f#ccbd3f8a1154122525ca92ce56a2714", pwd);
        System.out.println("----------原文：" + text);
        System.out.println("----------密文：" + pwd);
        System.out.println("---------还原后：" + str);


    }

}
